//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================



using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace GuidanceExplorer.Model
{
    /// <summary>
    /// This class represents a generic View and Folder structure container.
    /// </summary>
    public abstract class FolderStructure : IGuidanceItemContainer
    {
        protected FolderStructure()
        {
            Id = Guid.NewGuid().ToString();
        }

        /// <summary>
        /// The unique identifier for the folder structure
        /// </summary>
        [Browsable(true)]
        public string Id { get; private set; }

        /// <summary>
        /// The list of root folders.
        /// </summary>
        private FolderCollection _folders = FolderCollection.New();

        /// <summary>
        /// The list of views collection.
        /// </summary>
        private ViewCollection _views = ViewCollection.New();

        private ChecklistCollection _checklists = ChecklistCollection.New();

        /// <summary>
        /// The columns for the root container.
        /// </summary>
        private ColumnCollection _columns = ColumnCollection.New();

        /// <summary>
        /// The list of root folders.
        /// </summary>
        [Browsable(false)]
        public FolderCollection Folders
        {
            get { return _folders; }
        }

        /// <summary>
        /// The list of root views.
        /// </summary>
        [Browsable(false)]
        public ViewCollection Views
        {
            get { return _views; }
        }

        [Browsable(false)]
        public ChecklistCollection Checklists 
        {
            get { return _checklists; } 
        }

        /// <summary>
        /// The list of all child views.
        /// </summary>
        [Browsable(false)]
        public ViewCollection AllViews
        {
            get 
            {
                ViewCollection views = ViewCollection.New();
                foreach( View view in _views.Values )
                {
                    views.Add(view.Id, view);
                }

                foreach (Folder folder in _folders.Values)
                {
                    foreach (View view in folder.AllViews.Values)
                    {
                        views.Add(view.Id, view);
                    }
                }

                return views; 
            }
        }


        /// <summary>
        /// The columns for the root container.
        /// </summary>
        [Browsable(false)]
        public ColumnCollection Columns
        {
            get { return _columns; }
            set { _columns = value; }
        }

        /// <summary>
        /// FolderStructures does not have items.
        /// </summary>
        [Browsable(false)]
        public virtual bool HasItems
        {
            get { return false; }
        }

        /// <summary>
        /// The items collection can't be set.
        /// </summary>
        [Browsable(false)]
        public bool CanSetItems
        {
            get { return false; }
        }

        /// <summary>
        /// The list of items in the container.
        /// </summary>
        [Browsable(false)]
        public virtual GuidanceItemCollection Items
        {
            get
            {
                GuidanceItemCollection collection = GuidanceItemCollection.New();
                foreach (Folder folder in _folders.Values)
                {
                    foreach (GuidanceItem item in folder)
                    {
                        if (!collection.ContainsKey(item.Id))
                        {
                            collection.Add(item.Id, item);
                        }
                    }
                }
                foreach (View view in _views.Values)
                {
                    foreach (GuidanceItem item in view)
                    {
                        if (!collection.ContainsKey(item.Id))
                        {
                            collection.Add(item.Id, item);
                        }
                    }
                }
                return collection;
            }

            set { throw new Exception("Folders does not have Items."); }
        }

        #region IEnumerable<GuidanceItem> Members

        public virtual IEnumerator<GuidanceItem> GetEnumerator()
        {
            foreach (Folder folder in _folders.Values)
            {
                foreach (GuidanceItem item in folder)
                {
                    yield return item;
                }
            }

            foreach (View view in _views.Values)
            {
                //if (!(view is SearchView))
                {
                    foreach (GuidanceItem item in view)
                    {
                        yield return item;
                    }
                }
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        public override bool Equals(object obj)
        {
            FolderStructure other = obj as FolderStructure;
            if (other != null)
            {
                bool columns = (_columns.Equals(other._columns));
                bool folders = (_folders.Equals(other._folders));
                bool views = (_views.Equals(other._views));
                return (columns && folders && views);
            }
            else
            {
                return base.Equals(obj);
            }
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Return whether the items added to this root container must be copied by value
        /// </summary>
        [Browsable(false)]
        public virtual bool CopyItemsByValue { get { return false; } }
    }
}

